package com.liz.lizrpccore.lizspring.postprocessor;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.liz.lizrpcapi.commons.Node;
import com.liz.lizrpccore.annotations.CustomerResource;
import com.liz.lizrpccore.beans.ResourceBean;
import com.liz.lizrpccore.core.LizRpcConfig;
import com.liz.lizrpccore.entity.UniqueClientId;
import com.liz.lizrpccore.utils.LizStringUtil;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Map;
import java.util.Set;

/**
 * @author liangGongWei
 * @description
 * @create 2022-04-11 17:35
 **/

public class CustomerResourceAnnotationBeanPostProcessorBack implements SmartInitializingSingleton {

    /**
     * TODO 这里以SmartInitializingSingleton的方式，在bean全部实例化完成后，再将 CustomerResource 修饰的属性注入,不太行，因为可能创建了动态代理
     */

    private final Logger logger = LoggerFactory.getLogger(getClass());

    public static final String BEAN_NAME = "referenceAnnotationBeanPostProcessor";

    private ListableBeanFactory beanFactory;


    public CustomerResourceAnnotationBeanPostProcessorBack(ListableBeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }


    @Override
    public void afterSingletonsInstantiated() {
        String[] beanNames = beanFactory.getBeanNamesForType(Object.class);
        for (String beanName : beanNames) {
            Object bean = beanFactory.getBean(beanName);
            Class<?> aClass = bean.getClass();

            Field[] fields = aClass.getDeclaredFields();
            for (Field field : fields) {
                if (!field.isAnnotationPresent(CustomerResource.class)) {
                    continue;
                }
                String key = LizStringUtil.toLowerFirstLetterCase(field.getType().getName());

                field.setAccessible(true);
                try {
                    ResourceBean lizRpcProxy = this.getLizRpcProxy(key);
                    if (null == lizRpcProxy) {
                    } else {
                        Object object = lizRpcProxy.getObject();
                        field.set(bean, object);
                    }
                } catch (Throwable t) {
                    logger.warn("注入失败-bean:{},field:{}", beanName, key);
                }
            }
        }
    }


    private ResourceBean getLizRpcProxy(String className) {
        try {
            Class<?> interfaceType = Class.forName(className);
            return new ResourceBean<>(interfaceType);
        } catch (Throwable t) {
            logger.warn("create proxy Object failed，error:{}", t.getMessage());
            return null;
        }
    }




}
